
#define WIN32_LEAN_AND_MEAN
//#include "GameDemo.h"

#include "Goble.h"
#include "DDraw.h"
#include "Image.h"
#include "Map.h"
#include "Xuan.h"
#include "DInput.h"
#include "Bullet.h"
#include "Monster.h"
#include <windows.h>   // include important windows stuff
#include <windowsx.h> 
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////////////////////////////
////////////DEFINES
/////////////////////////////////////////////////////////////////////////////////////////////////

//name for our window class

#define  WINDOWCLASS TEXT("GameDemo")

//Title for the application
#define  WINDOWTitle TEXT("GameDemo")

//////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////INCLUDES
//////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////
//////////PROTOTYPES
///////////////////////////////////////////////////////////////////////////////////////////////

bool Game_Init();     //game data initializer
void Game_Loop();     //main game loop
void Game_Clean();    //game cleanup


/////////////////////////////////////////////////////////////////////////////////////////////////
//////////GLOBLES
////////////////////////////////////////////////////////////////////////////////////////
HINSTANCE hInstMain=NULL;  //main application handle
HWND hWndMain=NULL;          //handle to our main window
bool windowed=true;
int WindowWidth=800;
int WindowHeight=600;
int worldPosition=0;

Map *map=new Map(10);
Xuan *xuan=new Xuan();
Image mapImage;
DDraw ddraw;
DInput dinput;
Bullet * bullet=new Bullet(50);
Monster* mon=new Monster();

//////////////////////////////////////////////////////////////////////////////////////////////
/////////WINDOWPROC
//////////////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	//which messge did we get?
	switch(uMsg)
	{
	case WM_DESTROY ://the window is being destroyed
		{

			//tell the application we are quitting
			PostQuitMessage(0);

			//handle  message,so return 0
			return 0;
		}break;
	
	}

	//pass along any other message to default message handler
	return (DefWindowProc(hwnd,uMsg,wParam,lParam));

}

/////////////////////////////////////////////////////////////////////////////////////
////////WINMAIN
/////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine, int nShowCmd)
{
	//assign instance to global variable
	hInstMain=hInstance;
	freopen( "ERROR.txt" , "w" , stdout ) ;

	//creat window class
	WNDCLASSEX wcx;

	//set the size of the structure
	wcx.cbSize=sizeof(WNDCLASSEX);

	//class style
	wcx.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;

	//window procedure
	wcx.lpfnWndProc=WinProc;

	//class extra
	wcx.cbClsExtra=0;

	//window extra
	wcx.cbWndExtra=0;

	//application handle
	wcx.hInstance=hInstMain;

	//icon
	wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);

	//cursor
	wcx.hCursor=LoadCursor(NULL,IDC_ARROW);

	//background color
	wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);

	//menu
	wcx.lpszMenuName=NULL;

	//class name
	wcx.lpszClassName=WINDOWCLASS;

	//small icon
	wcx.hIconSm=NULL;

	//register the window class, return 0 if not successful
	if(!RegisterClassEx(&wcx))
	{
		fprintf (stdout , "RegisterClassEx(&wcx)----FAILED\n" ) ;
		return 0;
	}

	//create main window
	if(!(hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTitle,
								(windowed ? (WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION) : (WS_POPUP | WS_VISIBLE)),
								0,0,WindowWidth,WindowHeight,NULL,NULL,hInstMain,NULL)))
	{

		fprintf (stdout , "CreateWindowEx()----FAILED\n" ) ;
		return 0;
	}

	if (windowed==true)
	{
		// now resize the window, so the client area is the actual size requested
		// since there may be borders and controls if this is going to be a windowed app
		// if the app is not windowed then it won't matter
		RECT window_rect = {0,0,WindowWidth-1,WindowHeight-1};


		// make the call to adjust window_rect
		AdjustWindowRectEx(&window_rect,
			GetWindowStyle(hWndMain),
			GetMenu(hWndMain) != NULL,
			GetWindowExStyle(hWndMain));

		// now resize the window with a call to MoveWindow()
		MoveWindow(hWndMain,
			0, // x position
			0, // y position
			window_rect.right - window_rect.left, // width
			window_rect.bottom - window_rect.top, // height
			FALSE);

		// show the window, so there's no garbage on first render
		ShowWindow(hWndMain, SW_SHOW);
	} // end if windowed
	
	//if program initialization failed ,return with 0
	if(!Game_Init())
	{
		fprintf (stdout , "Game_Init()----FAILED\n" ) ;
		return 0;
	}

	//message structure
	MSG msg;

	//message pump
	while(true)
	{
		//look for a message
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			//there is a message

			//check that we aren't quitting
			if(msg.message==WM_QUIT)
				break;

			//translate message
			TranslateMessage(&msg);

			//dispatch message
			DispatchMessage(&msg);
		}

		//run main game loop
		Game_Loop();
	}

	//clean up program data
	Game_Clean();

	//return the wparam from the WM_QUIT message
	return msg.wParam;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////INITIALZATION
//////////////////////////////////////////////////////////////////////////////////////////////////

bool Game_Init()
{
	///////////////////////////////////////////////////////
	//////////your initialization code goes here
	///////////////////////////////////////////////////////
	dinput.init(hWndMain,hInstMain);
	ddraw.Init(hWndMain,windowed,WindowWidth,WindowHeight);


	mapImage.LoadImage("alley24.bmp");
	for(int i=0;i<8;i++)
	{
		map->CreateSurface(ddraw.GetMainPointer(),BackGround,i,125,750);
		map->LoadImage(mapImage,BackGround,i,i,0);
	}
	mapImage.DeleteImage();

	mapImage.LoadImage("grass.bmp");
	for(int i=0;i<4;i++)
	{
		map->CreateSurface(ddraw.GetMainPointer(),Floor,i,103,140);
		map->LoadImage(mapImage,Floor,i,i,0);
	}
	mapImage.DeleteImage();

	mapImage.LoadImage("bb.bmp");
	for (int i=0;i<2;i++)
	{
		map->CreateSurface(ddraw.GetMainPointer(),Block,i,120,32);
		map->LoadImage(mapImage,Block,i,0,0);
	}
	mapImage.DeleteImage();

	mapImage.LoadImage("dragon1.bmp");
	bullet->CreateSurface(ddraw.GetMainPointer(),60,60,0);
	bullet->LoadImage(mapImage,0);
	mapImage.DeleteImage();

	mapImage.LoadImage("dragon2.bmp");
	bullet->CreateSurface(ddraw.GetMainPointer(),60,60,1);
	bullet->LoadImage(mapImage,1);
	mapImage.DeleteImage();

	int a[]={0,1,2,3,4,5,6,7,0};
	map->MapAddInfo(BackGround,a,8);
	int b[]={0,1,2,1,2,1,2,1,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,3};
	map->MapAddInfo(Floor,b,24);
	int c[]={1,1,1,1};
	map->MapAddInfo(Block,c,4);
	POINT d[]={{200,200},{500,500},{700,450},{1000,350}};
	map->SetBlockPoint(d);

	mapImage.LoadImage("p.bmp");
	for (int i=0;i<2;i++)
	{
		for (int j=0;j<4;j++)
		{
			xuan->CreateSurface(ddraw.GetMainPointer(),i*4+j,57,70);
			xuan->LoadImage(mapImage,i*4+j,j,i);

			mon->CreateSurface(ddraw.GetMainPointer(),i*4+j,57,70);
			mon->LoadImageA(mapImage,i*4+j,j,i);
		}
	}
	mapImage.DeleteImage();

	xuan->setBullet(bullet);

	POINT limit;
	limit.x=800;
	limit.y=600;
	xuan->setLimitRect(&limit);
	map->setLimitRect(&limit);

	POINT nPoint[]={{100,100},{400,300},{700,100}};
	mon->addMonster(3,nPoint);
	return true;        //return succuss
}

////////////////////////////////////////////////////////////////////////////////////////////////
//////////////// CLEANUP
///////////////////////////////////////////////////////////////////////////////////////////////
void Game_Clean()
{
	/////////////////////////////////////////////////
	////clean code goes here
	/////////////////////////////////////////////////
}

//////////////////////////////////////////////////////////////////////////////////////////////
/////////////// MAIN GAME LOOP
//////////////////////////////////////////////////////////////////////////////////////////////

void Game_Loop()
{
	/////////////////////////////////////////////
	//////////main game logoc goes here
	/////////////////////////////////////////////
	DWORD timestart=GetTickCount();
	dinput.GetKeyboardData();
	dinput.CheckEsc(hWndMain);
	dinput.UpInfoPosition(&worldPosition,map,xuan,mon,bullet);

	
	map->BackGroundScroll(ddraw.GetBackSurface(),BackGround);
	map->BackGroundScroll(ddraw.GetBackSurface(),Floor);
	map->BlockDraw(ddraw.GetBackSurface());


	bullet->update();
	bullet->draw(ddraw.GetBackSurface());

	xuan->move(map);
	xuan->BltToSurface(ddraw.GetBackSurface(),xuan->getCurrentFrame());

	mon->action(ddraw.GetBackSurface(),map,bullet);


	//====================================================================================================================
	HDC xdc; // the working dc

	// get the dc from surface
	ddraw.GetBackSurface()->GetDC(&xdc);

	// set the colors for the text up
	SetTextColor(xdc,RGB(0,0,0));

	// set background mode to transparent so black isn't copied
	SetBkMode(xdc, TRANSPARENT);

	char  text[80];

	for (int i=0;i<map->GetBLOCK().node.length;i++)
	{
		sprintf(text,"%d  %d  %d  %d",map->GetBLOCK().node.faceRect[i].left,map->GetBLOCK().node.faceRect[i].right,map->GetBLOCK().node.faceRect[i].top,map->GetBLOCK().node.faceRect[i].bottom);
		TextOut(xdc,10,30+i*20,text,strlen(text));
	}
	sprintf(text,"%d  %d  ",map->GetWorldPoint(Floor),map->GetWorldPoint(BackGround));

	TextOut(xdc,10,500,text,strlen(text));

	sprintf(text,"%d  %d",xuan->getWorld().x,xuan->getWorld().y);

	TextOut(xdc,10,530,text,strlen(text));
	
	ddraw.GetBackSurface()->ReleaseDC(xdc);

	//====================================================================================================================
	ddraw.Flip(hWndMain,windowed);
	
	while(GetTickCount()-timestart<33);
}
	